package com.hy.common.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.hy.common.consts.CommonConst;
import com.hy.common.pool.ThreadPool;
import com.hy.common.utils.MD5Utils;
import com.hy.common.utils.MyObjectUtils;
import com.hy.common.utils.StateUtil;
import com.hy.entity.pojo.HyDepartment;
import com.hy.entity.pojo.HyUnit;
import com.hy.entity.pojo.HyUser;

import com.hy.entity.vo.UserReadVO;
import com.hy.mapper.HyDepartmentMapper;
import com.hy.mapper.HyUnitMapper;
import com.hy.mapper.HyUserMapper;
import com.hy.service.SysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;



import java.text.SimpleDateFormat;
import java.util.*;

import java.util.concurrent.atomic.AtomicInteger;

public class UserExcelImport extends AbstractExcelImport<UserReadVO,HyUser>{


    private Integer count= 0;

    private final AtomicInteger realCount=new AtomicInteger(0);
    private SysUserService userService;

    private Integer runTimes=0;
    private HyUnitMapper unitMapper;

    private String lock;
    private HyDepartmentMapper departmentMapper;

    private HyUserMapper userMapper;

    public void setLock(String lock) {
        this.lock = lock;
    }

    public Integer getCount() {
        return count;
    }

    public UserExcelImport(SysUserService userService, HyUnitMapper unitMapper, HyDepartmentMapper departmentMapper, HyUserMapper userMapper) {
        this.userService = userService;
        this.unitMapper = unitMapper;
        this.departmentMapper = departmentMapper;
        this.userMapper = userMapper;

    }

    public Integer getRunTimes() {
        return runTimes;
    }

    public AtomicInteger getRealCount() {
        return realCount;
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        boolean valid = validateHeader(headMap);
        if (!valid) {

            throw new RuntimeException("表头校验失败，请检查Excel文件的列名");
        }

    }
    private boolean validateHeader(Map<Integer, String> headMap) {

        Set<String> expectedHeaders=new HashSet<>();
        Collections.addAll(expectedHeaders,"用户名","密码","所属单位","所属部门","性别","手机");
        Set<String> actualHeaders = new HashSet<>(headMap.values());
        return actualHeaders.containsAll(expectedHeaders);
        // 检查表头是否与预期的列名一致
    }
    @Override
    public void invoke(UserReadVO object, AnalysisContext context) {
        runTimes++;
        if (MyObjectUtils.areAllFieldsNull(object)) {
            count--;
            runTimes--;
            return;
        }
        ThreadPool.poolExecutor.execute(()->{
                try{
                    HyUser user=new HyUser();
                    BeanUtils.copyProperties(object,user);
                    HyUnit hyUnit = unitMapper.selectOne(new LambdaQueryWrapper<HyUnit>().and(hyUnitLambdaQueryWrapper ->
                            hyUnitLambdaQueryWrapper.eq(HyUnit::getUnitName,object.getUnit())
                    ));
                    Optional<HyUnit> hyUnit1 = Optional.ofNullable(hyUnit);
                    if (ObjectUtils.isEmpty(hyUnit1)){
                        throw new  ExcelAnalysisException("单位信息有误");
                    }

                    hyUnit1.ifPresent(e->{
                        HyDepartment department = departmentMapper.selectOne(new LambdaQueryWrapper<HyDepartment>().and(wapper->
                                wapper.eq(HyDepartment::getDepartmentName,object.getDepartment()).eq(HyDepartment::getUnitId,hyUnit.getUnitId())
                        ));
                        Optional<HyDepartment> department1 = Optional.ofNullable(department);
                        if(ObjectUtils.isEmpty(department1)){
                            throw new ExcelAnalysisException("部门信息有误！");
                        }
                        department1 .ifPresent(m->{
                            HyUser hyUser = userMapper.selectOne(new LambdaQueryWrapper<HyUser>().and((wapper ->
                                    wapper.eq(HyUser::getUsername, object.getUsername())
                                            .eq(HyUser::getUnitId, hyUnit.getUnitId())
                            )));
                            if (hyUser==null) {
                                user.setDel(1);
                                user.setPassword(MD5Utils.encrypt(object.getPassword(), MD5Utils.MD5_KEY, 1));
                                user.setUnitId(hyUnit.getUnitId());
                                user.setDepartmentId(department.getDepartmentId());
                                user.setSex(StateUtil.getSex(object.getSex()).byteValue());
                                Long createDateTime=new Date().getTime()+ CommonConst.GMT_TIME;
                                SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                String dateTime = simpleDateFormat.format(new Date(createDateTime));
                                user.setCreateDate(dateTime);
                                user.setUpdateDate(dateTime);
                            }else {
                                throw    new ExcelAnalysisException("人名有误");
                            }
                        });
                    });
                    dataList.add(user);
                    realCount.incrementAndGet();
                    if (runTimes.equals(realCount.get())){
                        doSaveData(dataList);
                        synchronized (lock){
                            lock.notifyAll();
                        }
                    }
                }
                catch (ExcelAnalysisException e){
                    e.printStackTrace();
                    synchronized (lock){
                        lock.notifyAll();
                    }

                    throw  e;
                }
            });
     }



    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        this.count=analysisContext.getTotalCount()+this.count;
    }

    @Override
    protected void doSaveData(List<HyUser> data) {
        userService.saveStuListWithBatch(data);
    }
}
